// Tetris.cpp : 定义应用程序的入口点。
//
 
/*
记录于2016-5-29 星期日    由于闪屏过于显眼，采用双缓冲
 
*/
 
#include "stdafx.h"
#include "Tetris.h"
#include "windows.h"
#include <mmsystem.h>
#pragma comment(lib, "WINMM.LIB")
#define MAX_LOADSTRING 100
 
// 此代码模块中包含的函数的前向声明:
ATOM                MyRegisterClass(HINSTANCE hInstance);//注册窗口类
BOOL                InitInstance(HINSTANCE, int);//初始化
LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);//窗口消息处理函数
INT_PTR CALLBACK    About(HWND, UINT, WPARAM, LPARAM);//对话框处理
 
// 全局变量:
HINSTANCE hInst;                                // 当前实例
TCHAR szTitle[MAX_LOADSTRING];                  // 标题栏文本
TCHAR szWindowClass[MAX_LOADSTRING];            // 主窗口类名
 
int APIENTRY _tWinMain(HINSTANCE hInstance,//当前句柄
                     HINSTANCE hPrevInstance,//父窗口句柄
                     LPTSTR    lpCmdLine,//指向程序命令行参数的指针
                     int       nCmdShow)//指定窗口如何显示
{
    init_game();//初始化游戏
    UNREFERENCED_PARAMETER(hPrevInstance);//hPrevInstance参数使用过了，避免编译器报警告
    UNREFERENCED_PARAMETER(lpCmdLine);
 
    // TODO: 在此放置代码。
    MSG msg;//消息
    HACCEL hAccelTable;//调入加速键表的句柄
 
    // 初始化全局字符串
    LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);// 导入字符串资源
    LoadString(hInstance, IDC_TETRIS, szWindowClass, MAX_LOADSTRING);// 导入字符串资源
    MyRegisterClass(hInstance);// 调用注册窗口函数
 
    // 执行应用程序初始化:
    if (!InitInstance (hInstance, nCmdShow))
    {
        return FALSE;//初始化失败
    }
 
    hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_TETRIS));// 导入指定的加速键表
 
    // 主消息循环:
    while (1)
    {
        if (PeekMessage(&msg,0,0,0,PM_REMOVE))//查询消息队列，从消息队列中取出消息
        {
            TranslateMessage(&msg);//将消息的虚拟键转化为字符消息
			DispatchMessage(&msg);//将消息传送到指定窗口函数
            if (msg.message==WM_QUIT)//关闭消息循环，则终止程序
            {
                break;//程序关闭，退出循环
            }
        }
        else
        {
            if ((GAME_STATE&2)!=0)
            {
                tCur = GetTickCount();//求运行时间
                if (tCur-tPre>g_speed)////启动后经过时间大于g_speed
                {
 
                    int flag = CheckValide(curPosX,curPosY+1,bCurTeris);//检查下一行的情况，返回结果给flag
                    if (flag==1)//能下降一行
                    {
                        curPosY++;//下降一行
                        tPre = tCur;////重新计算时间
                        HWND hWnd = GetActiveWindow();//获得与调用线程的消息队列相关的活动窗口的窗口句柄
                        InvalidateRect(hWnd,&rc_left,FALSE);
						//向指定的窗体更新区域添加一个矩形，重新绘制时不擦除背景
                        InvalidateRect(hWnd,&rc_right_top,FALSE);
                    }
                    else if (flag==-2)//方块到底
                    {
                        g_speed = t_speed;//更新速度
                        fillBlock();//填充
                        checkComplite();//是否能消去一行
                        setRandomT();//随机产生方块
                        curPosX = (NUM_X-4)>>1;//设置方块坐标X
                        curPosY = 0;//设置方块坐标Y
                        HWND hWnd = GetActiveWindow();//获得与调用线程的消息队列相关的活动窗口的窗口句柄
                        InvalidateRect(hWnd,&rc_main,FALSE);//刷新矩形区域
                    }
                    else if(flag==-3)//方块到顶（游戏失败）
                    {
                        HWND hWnd = GetActiveWindow();//获得与调用线程的消息队列相关的活动窗口的窗口句柄
                        if (MessageBox(hWnd,L"胜败乃兵家常事，菜鸡请重新来过",L":时光机",MB_YESNO)==IDYES)
                        {
                            init_game();//若提示框中选择重来，初始化游戏
                        }
                        else
                        {
                            break;//否则退出主消息循环
                        }
                    }
                }
            }
        }
    }
 
    return (int) msg.wParam;
}
 
 
//
//  函数: MyRegisterClass()
//
//  目的: 注册窗口类。
//
//  注释:
//
//    仅当希望
//    此代码与添加到 Windows 95 中的“RegisterClassEx”
//    函数之前的 Win32 系统兼容时，才需要此函数及其用法。调用此函数十分重要，
//    这样应用程序就可以获得关联的
//    “格式正确的”小图标。
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
    WNDCLASSEX wcex;
 
    wcex.cbSize = sizeof(WNDCLASSEX);;//窗口类的大小
									  //CS_HREDRAW:一旦移动或尺寸调整使客户区的宽度、高度发生变化，就重新绘制窗口 
 
    wcex.style          = CS_HREDRAW | CS_VREDRAW;//窗口样式
    wcex.lpfnWndProc    = WndProc;//窗口处理函数为WndProc
    wcex.cbClsExtra     = 0;////窗口类无扩展
    wcex.cbWndExtra     = 0;//窗口无实例扩展
    wcex.hInstance      = hInstance;//当前实例句柄
    wcex.hIcon          = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_TETRIS));//窗口的图标为默认图标
    wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);//鼠标
    wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);//窗口背景默认为白色
    wcex.lpszMenuName   = MAKEINTRESOURCE(IDC_TETRIS);//窗口菜单为自定义菜单
    wcex.lpszClassName  = szWindowClass;//设置窗口类名为szWindowClass
    wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));//窗口的小图标为默认图标
 
 
    return RegisterClassEx(&wcex);
}
 
//
//   函数: InitInstance(HINSTANCE, int)
//
//   目的: 保存实例句柄并创建主窗口
//
//   注释:
//
//        在此函数中，我们在全局变量中保存实例句柄并
//        创建和显示主程序窗口。
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
   HWND hWnd;
 
   hInst = hInstance; // 将实例句柄存储在全局变量中
 //创建窗口
   hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
   if (!hWnd)
   {
      return FALSE;
   }
 
   ShowWindow(hWnd, nCmdShow);//显示窗口
   UpdateWindow(hWnd);//重绘用户区
 
   return TRUE;
}
 
//
//  函数: WndProc(HWND, UINT, WPARAM, LPARAM)
//
//  目的: 处理主窗口的消息。
//
//  WM_COMMAND  - 处理应用程序菜单
//  WM_PAINT    - 绘制主窗口
//  WM_DESTROY  - 发送退出消息并返回
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    int wmId, wmEvent;
    PAINTSTRUCT ps;//该结构体包含了某应用程序用来绘制它所拥有的窗口客户区所需要的信息
    HDC hdc;//设备环境句柄
    int nWinx,nWiny,nClientX,nClientY;
    int posX,posY;
    RECT rect;//用来存储成对出现的参数
    HMENU hSysmenu;//菜单窗口的句柄
    switch (message)
    {
    case WM_CREATE://CreateWindow创建窗口时发送此消息
         
 
        GetWindowRect(hWnd,&rect);//该函数返回指定窗口的边框矩形的尺寸
        nWinx = 530;//窗口宽度
        nWiny = 680;//窗口高度
        posX = GetSystemMetrics(SM_CXSCREEN);//获取屏幕宽度
		posY = GetSystemMetrics(SM_CYSCREEN);//获取屏幕高度
		posX = (posX - nWinx) >> 1;//居中时X位置
		posY = (posY - nWiny) >> 1;//居中时Y位置
		GetClientRect(hWnd, &rect);//获取窗口用户区尺寸
		nClientX = rect.right - rect.left;//窗口用户区X值
		nClientY = rect.bottom - rect.top;//窗口用户区Y值
 
        MoveWindow(hWnd,posX,posY,530,680,TRUE);//设置窗口位置和大小
        hSysmenu = GetSystemMenu(hWnd,false);//允许应用程序为复制或修改而访问窗口菜单
        AppendMenu(hSysmenu,MF_SEPARATOR,0,NULL);//添加一个新菜单
        AppendMenu(hSysmenu,0,IDM_DIFF,L"难度选择");
        break;
    case WM_COMMAND://点击菜单、按钮、下拉列表框等控件时触发
        wmId    = LOWORD(wParam);//取wParam的低位
        wmEvent = HIWORD(wParam);//取wParam的高位
        // 分析菜单选择:
        switch (wmId)
        {
        case IDM_ABOUT:
            DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
            break;
        case IDM_EXIT:
            DestroyWindow(hWnd);
            break;
        case ID_dif1:
            selectDiffculty(hWnd,1);
            break;
        case ID_dif2:
            selectDiffculty(hWnd,2);
            break;
        case ID_dif3:
            selectDiffculty(hWnd,3);
            break;
        case ID_LAYOUT1:
            selectLayOut(hWnd,1);
            break;
        case ID_LAYOUT2:
            selectLayOut(hWnd,2);
            break;
        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
        }
        break;
    case WM_KEYDOWN://当一个非系统键被按下时该消息发送给具有键盘焦点的窗口 
        hdc = GetDC(hWnd);//检索一指定窗口的客户区域或整个屏幕的显示设备上下文环境的句柄
        InvalidateRect(hWnd,NULL,false);
        switch(wParam)
        {
        case VK_LEFT:
            curPosX--;//当前X值减一
            if(CheckValide(curPosX,curPosY,bCurTeris)!=1)
            {
                curPosX++;//若已超过左边界，X+1
            }
            break;
        case VK_RIGHT:
            curPosX++;
            if(CheckValide(curPosX,curPosY,bCurTeris)!=1)
            {
                curPosX--;
            }
            break;
        case VK_UP:
            RotateTeris(bCurTeris);//旋转矩阵
            break;
        case VK_DOWN:
            if (g_speed==t_speed)
                g_speed =10 ;
            else
                g_speed = t_speed;
            //outPutBoxInt(g_speed);
            break;
        case 'W'://up
            RotateTeris(bCurTeris);
            break;
        case 'A'://left
            curPosX--;
            if(CheckValide(curPosX,curPosY,bCurTeris)!=1)
            {
                curPosX++;
            }
            break;
        case 'D'://right
            curPosX++;
            if(CheckValide(curPosX,curPosY,bCurTeris)!=1)
            {
                curPosX--;
            }
            break;
         
        case 'S'://down
            if (g_speed==t_speed)
                g_speed =10 ;
            else
                g_speed = t_speed;
            //outPutBoxInt(g_speed);
            break;
        default:
            break;
        }
 
    case WM_PAINT:
        hdc = BeginPaint(hWnd, &ps);//为指定窗口进行绘图准备
        // TODO: 在此添加任意绘图代码...
        DrawBackGround(hdc);//绘制背景
        EndPaint(hWnd, &ps);//停止绘制
        break;
    case WM_DESTROY:
        PostQuitMessage(0);//退出传递给消息
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}
 
// “关于”框的消息处理程序。
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    UNREFERENCED_PARAMETER(lParam);
    switch (message)
    {
    case WM_INITDIALOG://对话框及其所有子控件都创建完毕
        return (INT_PTR)TRUE;
 
    case WM_COMMAND:
        if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
        {
            EndDialog(hDlg, LOWORD(wParam));//清除关于对话框,并使系统中止对对话框的任何处理
            return (INT_PTR)TRUE;
        }
        break;
    }
    return (INT_PTR)FALSE;
}
 
 
void drawBlocked(HDC mdc)//绘制已经存在方块的区域
{
    int i,j;
 
    HBRUSH hBrush = (HBRUSH)CreateSolidBrush(RGB(255,255,0));//画刷句柄，创建黄色的逻辑刷子
     
    SelectObject(mdc,hBrush);
 
    for (i=0;i<NUM_Y;i++)
    {
        for (j=0;j<NUM_X;j++)
        {
            if (g_hasBlocked[i][j])//若数组中存在值，则说明有方块
            {
                Rectangle(mdc,BORDER_X+j*BLOCK_SIZE,BORDER_Y+i*BLOCK_SIZE,
                    BORDER_X+(j+1)*BLOCK_SIZE,BORDER_Y+(i+1)*BLOCK_SIZE
                    );//绘制矩形
            }
        }
    }
    DeleteObject(hBrush);//删除对象
}
 
int CheckValide(int startX,int startY,BOOL bTemp[4][4])//给定一个矩阵，查看是否合法
{
    int i,j;
    for (i=3;i>=0;i--)
    {
        for (j=3;j>=0;j--)
        {
            if(bTemp[i][j])//判断落下的4*4中该位置上是否存在砖块
            {
                if (j+startX<0||j+startX>=NUM_X)//左右越界
                {
                    return -1;
                }
                if (i+startY>=NUM_Y)//下一行无法消除
                {
                    return -2;
                }
                if (g_hasBlocked[i+startY][j+startX])
                {
                    //outPutBoxInt(j+startY);
                    if (curPosY==0)//无下一行
                    {
                        return -3;
                    }
                    return -2;
                }
            }
        }
    }
    //MessageBox(NULL,L"这里",L"as",MB_OK);
    //outPutBoxInt(curPosY);
    return 1;
}
 
void checkComplite()//查看该行是否能消去  采用从上往下的消法，消去后把上面的下移
{
    int i,j,k,count=0;
    for (i=0;i<NUM_Y;i++)
    {
        bool flag = true;
        for (j=0;j<NUM_X;j++)
        {
            if(!g_hasBlocked[i][j])//i行j列缺少砖块，i行无法消除
            {
                flag = false;
            }
        }
        if (flag)//可消除
        {
            count++;
            for (j=i;j>=1;j--)
            {
                for (k=0;k<NUM_X;k++)
                {
                    g_hasBlocked[j][k] = g_hasBlocked[j-1][k];//令删除行之上的各行下移
                }
                 
            }
            drawCompleteParticle(i);
            Sleep(300);
             
            PlaySound(_T("coin.wav"),NULL,SND_FILENAME|SND_ASYNC);//消去一行时播放系统自带提示音
        }
    }
    GAME_SCORE += int(count*1.5);
}
 
 
//用于调试 
VOID outPutBoxInt(int num)
{
    TCHAR szBuf[1024];
    LPCTSTR str = TEXT("%d");
    wsprintf(szBuf,str,num);
    MessageBox(NULL,szBuf,L"aasa",MB_OK);
}
 
VOID outPutBoxString(TCHAR str[1024])
{
    TCHAR szBuf[1024];
    LPCTSTR cstr = TEXT("%s");
    wsprintf(szBuf,cstr,str);
    MessageBox(NULL,szBuf,L"aasa",MB_OK);
}
 
 
 
 
void setRandomT()//随机生成方块
{
    int rd_start = RandomInt(0,sizeof(state_teris)/sizeof(state_teris[0]));//初始下落方块，[0,7)上随机数
    int rd_next = RandomInt(0,sizeof(state_teris)/sizeof(state_teris[0]));//下一个下落方块
    //outPutBoxInt(rd_start);
    //outPutBoxInt(rd_next);
    //outPutBoxInt(rd_start);
    if (GAME_STATE==0)//程序刚开始
    {
        GAME_STATE = GAME_STATE | 0x0001;//标记程序已进行
        //outPutBoxInt(GAME_STATE);
        memcpy(bCurTeris,state_teris[rd_start],sizeof(state_teris[rd_start]));//令当前下落方块为初始的方块
        memcpy(bNextCurTeris,state_teris[rd_next],sizeof(state_teris[rd_next]));//记录下一个落方块
    }
    else//程序已有下落方块
    {
        memcpy(bCurTeris,bNextCurTeris,sizeof(bNextCurTeris));
        memcpy(bNextCurTeris,state_teris[rd_next],sizeof(state_teris[rd_next]));
    }
     
}
void init_game()
{
    GAME_SCORE = 0;
    setRandomT();
    curPosX = (NUM_X-4)>>1;//从中间下落
    curPosY = 0;//从最上方下落
     
     
    memset(g_hasBlocked,0,sizeof(g_hasBlocked));
	//设置绘制4*4矩形各个小方格的位置参数
    rc_left.left = 0;
    rc_left.right = SCREEN_LEFT_X;
    rc_left.top = 0;
    rc_left.bottom = SCREEN_Y;
 
    rc_right.left = rc_left.right+BORDER_X;
    rc_right.right = 180+rc_right.left;
    rc_right.top = 0;
    rc_right.bottom = SCREEN_Y;
 
    rc_main.left = 0;
    rc_main.right = SCREEN_X;
    rc_main.top = 0;
    rc_main.bottom = SCREEN_Y;
 
    rc_right_top.left = rc_right.left;
    rc_right_top.top = rc_right.top;
    rc_right_top.right = rc_right.right;
    rc_right_top.bottom = (rc_right.bottom) / 2;
 
    rc_right_bottom.left = rc_right.left;
    rc_right_bottom.top = rc_right_top.bottom+BORDER_Y;
    rc_right_bottom.right = rc_right.right;
    rc_right_bottom.bottom = rc_right.bottom;
     
    g_speed = t_speed = 1000-GAME_DIFF*280;//下落速度
}
 
void fillBlock()//到达底部后填充矩阵
{
    int i,j;
    for (i=0;i<4;i++)
    {
        for (j=0;j<4;j++)
        {
            if(bCurTeris[i][j])//根据下落方阵形状填充
            {
                g_hasBlocked[curPosY+i][curPosX+j] = 1;
            }
        }
    }
}
 
void RotateTeris(BOOL bTeris[4][4])//旋转矩阵
{
    BOOL bNewTeris[4][4];
    int x,y;
    for (x=0;x<4;x++)
    {
        for(y=0;y<4;y++)
        {
            bNewTeris[x][y] = bTeris[3-y][x];
            //逆时针：
            //bNewTeris[x][y] = bTeris[y][3-x];
        }
    }
    if (CheckValide(curPosX,curPosY,bNewTeris)==1)//是否可变换
    {
        memcpy(bTeris,bNewTeris,sizeof(bNewTeris));//更新方块形状
    }
 
}
 
int RandomInt(int _min,int _max)//随机数int
{
    srand((rd_seed++)%65532+GetTickCount());
    return _min+rand()%(_max-_min);
}
 
VOID DrawTeris(HDC mdc)//绘制下落的方块
{
 
    int i,j;
    HPEN hPen = (HPEN)GetStockObject(BLACK_PEN);
    HBRUSH hBrush = (HBRUSH)GetStockObject(WHITE_BRUSH);
    SelectObject(mdc,hPen);
    SelectObject(mdc,hBrush);
    for (i=0;i<4;i++)
    {
        for (j=0;j<4;j++)
        {
            if(bCurTeris[i][j])
            {
                Rectangle(mdc,(j+curPosX)*BLOCK_SIZE+BORDER_X,(i+curPosY)*BLOCK_SIZE+BORDER_Y,(j+1+curPosX)*BLOCK_SIZE+BORDER_X,(i+1+curPosY)*BLOCK_SIZE+BORDER_Y);
            }
        }
    }
    drawBlocked(mdc);
    DeleteObject(hPen);
    DeleteObject(hBrush);
}
 
VOID DrawBackGround(HDC hdc)//绘制背景
{
 
    HBRUSH hBrush = (HBRUSH)GetStockObject(GRAY_BRUSH);
    HDC mdc = CreateCompatibleDC(hdc);
    HBITMAP hBitmap = CreateCompatibleBitmap(hdc,SCREEN_X,SCREEN_Y);
 
    SelectObject(mdc,hBrush);
    SelectObject(mdc,hBitmap);
 
    HBRUSH hBrush2 = (HBRUSH)GetStockObject(WHITE_BRUSH);
    FillRect(mdc,&rc_main,hBrush2);
    Rectangle(mdc,rc_left.left+BORDER_X,rc_left.top+BORDER_Y,rc_left.right,rc_left.bottom);
    Rectangle(mdc,rc_right.left+BORDER_X,rc_right.top+BORDER_Y,rc_right.right,rc_right.bottom);
    DrawTeris(mdc);
    drawNext(mdc);
    drawScore(mdc);
    ::BitBlt(hdc,0,0,SCREEN_X,SCREEN_Y,mdc,0,0,SRCCOPY);
    DeleteObject(hBrush);
    DeleteDC(mdc);
    DeleteObject(hBitmap);
    DeleteObject(hBrush2);
 
 
    //  int x,y;
    //  HPEN hPen = (HPEN)GetStockObject(NULL_PEN);
    //  HBRUSH hBrush = (HBRUSH)GetStockObject(GRAY_BRUSH);
    //  SelectObject(hdc,hPen);
    //  SelectObject(hdc,hBrush);
    //  for (x = 0;x<NUM_X;x++)
    //  {
    //      for(y=0;y<NUM_Y;y++)
    //      {
    //          Rectangle(hdc,BORDER_X+x*BLOCK_SIZE,BORDER_Y+y*BLOCK_SIZE,
    //              BORDER_X+(x+1)*BLOCK_SIZE,
    //              BORDER_Y+(y+1)*BLOCK_SIZE);
    //      }
    //  }
}
 
void drawNext(HDC hdc)//绘制下一个方块
{
    int i,j;
    HBRUSH hBrush = (HBRUSH)CreateSolidBrush(RGB(0,188,0));
    SelectObject(hdc,hBrush);
    for (i=0;i<4;i++)
    {
        for (j=0;j<4;j++)
        {
            if(bNextCurTeris[i][j])
            {
                Rectangle(hdc,rc_right_top.left+BLOCK_SIZE*(j+1),rc_right_top.top+BLOCK_SIZE*(i+1),rc_right_top.left+BLOCK_SIZE*(j+2),rc_right_top.top+BLOCK_SIZE*(i+2));
            }
        }
    }
    HFONT hFont = CreateFont(30,0,0,0,FW_THIN,0,0,0,UNICODE,0,0,0,0,L"微软雅黑");
    SelectObject(hdc,hFont);
    SetBkMode(hdc,TRANSPARENT);
    SetBkColor(hdc,RGB(255,255,0));
    RECT rect;
    rect.left = rc_right_top.left+40;
    rect.top = rc_right_top.bottom -150;
    rect.right = rc_right_top.right;
    rect.bottom = rc_right_top.bottom;
    DrawTextW(hdc,TEXT("下一个"),_tcslen(TEXT("下一个")),&rect,0);
    DeleteObject(hFont);
    DeleteObject(hBrush);
}
 
void drawScore(HDC hdc)//绘制分数和当前难度
{
    HFONT hFont = CreateFont(30,0,0,0,FW_THIN,0,0,0,UNICODE,0,0,0,0,L"微软雅黑");
    SelectObject(hdc,hFont);
    SetBkMode(hdc,TRANSPARENT);
    SetBkColor(hdc,RGB(255,255,0));
    RECT rect;
    rect.left = rc_right_bottom.left;
    rect.top = rc_right_bottom.top;
    rect.right = rc_right_bottom.right;
    rect.bottom = rc_right_bottom.bottom;
    TCHAR szBuf[30];
    LPCTSTR cstr = TEXT("当前难度：%d");
    wsprintf(szBuf,cstr,GAME_DIFF);
    DrawTextW(hdc,szBuf,_tcslen(szBuf),&rect,DT_CENTER | DT_VCENTER);
 
    RECT rect2;
    rect2.left = rc_right_bottom.left;
    rect2.top = rc_right_bottom.bottom/2+100;
    rect2.right = rc_right_bottom.right;
    rect2.bottom = rc_right_bottom.bottom;
    TCHAR szBuf2[30];
    LPCTSTR cstr2 = TEXT("得分：%d");
    wsprintf(szBuf2,cstr2,GAME_SCORE);
    //outPutBoxInt(sizeof(szBuf));
    DrawTextW(hdc,szBuf2,_tcslen(szBuf2),&rect2,DT_CENTER | DT_VCENTER);
 
    DeleteObject(hFont);
}
 
int selectDiffculty(HWND hWnd,int diff)//选择难度
{
    TCHAR szBuf2[30];
    LPCTSTR cstr2 = TEXT("确认选择难度 %d 吗？");
    wsprintf(szBuf2,cstr2,diff);
    if (MessageBox(hWnd,szBuf2,L"难度选择",MB_YESNO)==IDYES)
    {
        GAME_DIFF = diff;
        InvalidateRect(hWnd,&rc_right_bottom,false);
        GAME_STATE |=2;
        init_game();
        return GAME_DIFF;
    }
    return -1;
}
 
int selectLayOut(HWND hWnd,int layout)//更改用户区布局
{
    NUM_X = 10*layout;
    NUM_Y = 20*layout;
    BLOCK_SIZE = 30/layout;
    GAME_STATE|=2;
    InvalidateRect(hWnd,&rc_right_bottom,false);
    init_game();
    return layout;
}
 
void drawCompleteParticle(int line)//为消去的以行画一行空白做出消去效果
{
    HWND hWnd = GetActiveWindow();
    HDC hdc = GetDC(hWnd);
    HBRUSH hBrush = (HBRUSH)GetStockObject(GRAY_BRUSH);
    HPEN hPen = (HPEN)CreatePen(PS_DOT,1,RGB(255,255,0));
    SelectObject(hdc,hBrush);
    SelectObject(hdc,hPen);
    Rectangle(hdc,BORDER_X,
        BORDER_Y+line*BLOCK_SIZE,
        BORDER_X+NUM_X*BLOCK_SIZE,
        BORDER_Y+BLOCK_SIZE*(1+line));
    DeleteObject(hBrush);
    DeleteObject(hPen);
}